#include <stddef.h>  // size_t
#include <stdint.h>  // uint8_t, int32_t, uint32_t
#include <stdlib.h>  // malloc, free

#define   R_OK                           0
#define   R_ERR_MEMORY_RUNOUT            1
#define   R_ERR_UNSUPPORTED              2
#define   R_ERR_OUTPUT_OVERFLOW          3
#define   R_ERR_INPUT_OVERFLOW           4

#define RET_WHEN_ERR(err_code)          { int ec = (err_code); if (ec)  return ec; }
#define RET_ERR_IF(err_code,condition)  { if (condition) return err_code; }



#define    ABS(x)           ( ((x) < 0) ? (-(x)) : (x) )                             // get absolute value
#define    CLIP(x,a,b)      ( ((x)<(a)) ? (a) : (((x)>(b)) ? (b) : (x)) )            // clip x between a~b
#define    RORi(x,y)        ( ((x)<<(32-(y))) | ((x)>>(y)) )

#define    METHOD_DEFAULT   0
#define    METHOD_TEXT      1

#define    SQUARD           2
#define    MXR_MUL          341
#define    MXR_DIV          1024
#define    MXR_UPD          8
#define    MXR_INIT         0x0c00U
#define    PW_MUL           509U
#define    P5_MUL           37

#define    MI               8U
#define    MC               1280U

#define    MINLEN           2
#define    MAXLEN           62

#define    LIMIT_SM0_TEXT   320U
#define    LIMIT_SM0        64U
#define    LIMIT_SM1        320U
#define    LIMIT_SM2        240U
#define    LIMIT_SM3        140U
#define    LIMIT_SM4        124U
#define    LIMIT_SM5        124U
#define    LIMIT_SM6        112U
#define    LIMIT_APM1       384U
#define    LIMIT_APM2       680U


#define MEM_ALLOC(type,p_arr,num,init,n_allocate_bytes) { \
    (p_arr) = (type*)malloc((num) * sizeof(type));        \
    (n_allocate_bytes) = 0;                               \
    if (p_arr) {                                          \
        size_t i;                                         \
        (n_allocate_bytes) = (num) * sizeof(type);        \
        for (i=0; i<(num); i++) {                         \
            (p_arr)[i] = (type)(init);                    \
        }                                                 \
    }                                                     \
}                                                         \



#define TAB_DT(i)   (512*17 / ((i)+(i)+3))
#define TAB_DTA(i)  (512*34 / ((i)+(i)+18))


const static uint8_t  TAB_len2ctx [] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,25,26,26,26,26,26,27 };


const static uint32_t TAB_squash  [] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 103, 103, 103, 104, 104, 105, 105, 105, 106, 106, 107, 107, 107, 108, 108, 109, 109, 110, 110, 110, 111, 111, 112, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 130, 131, 131, 132, 132, 133, 133, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 150, 150, 151, 151, 152, 152, 153, 154, 154, 155, 155, 156, 156, 157, 158, 158, 159, 159, 160, 161, 161, 162, 162, 163, 164, 164, 165, 166, 166, 167, 167, 168, 169, 169, 170, 171, 171, 172, 173, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180, 180, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, 194, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202, 203, 203, 204, 205, 206, 206, 207, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 221, 222, 223, 224, 225, 226, 226, 227, 228, 229, 230, 231, 232, 232, 233, 234, 235, 236, 237, 238, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 304, 305, 306, 307, 308, 309, 310, 311, 312, 314, 315, 316, 317, 318, 319, 320, 322, 323, 324, 325, 326, 327, 329, 330, 331, 332, 333, 335, 336, 337, 338, 339, 341, 342, 343, 344, 346, 347, 348, 349, 351, 352, 353, 354, 356, 357, 358, 359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 372, 374, 375, 376, 378, 379, 380, 382, 383, 385, 386, 387, 389, 390, 391, 393, 394, 396, 397, 398, 400, 401, 403, 404, 405, 407, 408, 410, 411, 413, 414, 416, 417, 419, 420, 421, 423, 424, 426, 427, 429, 430, 432, 433, 435, 437, 438, 440, 441, 443, 444, 446, 447, 449, 450, 452, 454, 455, 457, 458, 460, 462, 463, 465, 466, 468, 470, 471, 473, 474, 476, 478, 479, 481, 483, 484, 486, 488, 489, 491, 493, 495, 496, 498, 500, 501, 503, 505, 507, 508, 510, 512, 514, 515, 517, 519, 521, 522, 524, 526, 528, 530, 531, 533, 535, 537, 539, 540, 542, 544, 546, 548, 550, 552, 553, 555, 557, 559, 561, 563, 565, 567, 569, 570, 572, 574, 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, 596, 598, 600, 602, 604, 606, 608, 610, 612, 614, 616, 618, 620, 622, 624, 626, 628, 631, 633, 635, 637, 639, 641, 643, 645, 647, 650, 652, 654, 656, 658, 660, 662, 665, 667, 669, 671, 673, 676, 678, 680, 682, 684, 687, 689, 691, 693, 696, 698, 700, 702, 705, 707, 709, 712, 714, 716, 719, 721, 723, 725, 728, 730, 733, 735, 737, 740, 742, 744, 747, 749, 751, 754, 756, 759, 761, 764, 766, 768, 771, 773, 776, 778, 781, 783, 786, 788, 791, 793, 796, 798, 801, 803, 806, 808, 811, 813, 816, 818, 821, 824, 826, 829, 831, 834, 836, 839, 842, 844, 847, 850, 852, 855, 857, 860, 863, 865, 868, 871, 873, 876, 879, 882, 884, 887, 890, 892, 895, 898, 901, 903, 906, 909, 912, 914, 917, 920, 923, 926, 928, 931, 934, 937, 940, 943, 945, 948, 951, 954, 957, 960, 963, 965, 968, 971, 974, 977, 980, 983, 986, 989, 992, 995, 997, 1000, 1003, 1006, 1009, 1012, 1015, 1018, 1021, 1024, 1027, 1030, 1033, 1036, 1039, 1042, 1045, 1048, 1051, 1055, 1058, 1061, 1064, 1067, 1070, 1073, 1076, 1079, 1082, 1085, 1089, 1092, 1095, 1098, 1101, 1104, 1107, 1111, 1114, 1117, 1120, 1123, 1126, 1130, 1133, 1136, 1139, 1142, 1146, 1149, 1152, 1155, 1159, 1162, 1165, 1168, 1172, 1175, 1178, 1181, 1185, 1188, 1191, 1195, 1198, 1201, 1205, 1208, 1211, 1215, 1218, 1221, 1225, 1228, 1231, 1235, 1238, 1241, 1245, 1248, 1252, 1255, 1258, 1262, 1265, 1269, 1272, 1276, 1279, 1282, 1286, 1289, 1293, 1296, 1300, 1303, 1307, 1310, 1314, 1317, 1321, 1324, 1328, 1331, 1335, 1338, 1342, 1345, 1349, 1352, 1356, 1359, 1363, 1366, 1370, 1374, 1377, 1381, 1384, 1388, 1391, 1395, 1399, 1402, 1406, 1409, 1413, 1417, 1420, 1424, 1428, 1431, 1435, 1438, 1442, 1446, 1449, 1453, 1457, 1460, 1464, 1468, 1471, 1475, 1479, 1483, 1486, 1490, 1494, 1497, 1501, 1505, 1508, 1512, 1516, 1520, 1523, 1527, 1531, 1535, 1538, 1542, 1546, 1550, 1553, 1557, 1561, 1565, 1569, 1572, 1576, 1580, 1584, 1587, 1591, 1595, 1599, 1603, 1607, 1610, 1614, 1618, 1622, 1626, 1629, 1633, 1637, 1641, 1645, 1649, 1653, 1656, 1660, 1664, 1668, 1672, 1676, 1680, 1683, 1687, 1691, 1695, 1699, 1703, 1707, 1711, 1714, 1718, 1722, 1726, 1730, 1734, 1738, 1742, 1746, 1750, 1754, 1757, 1761, 1765, 1769, 1773, 1777, 1781, 1785, 1789, 1793, 1797, 1801, 1805, 1809, 1813, 1816, 1820, 1824, 1828, 1832, 1836, 1840, 1844, 1848, 1852, 1856, 1860, 1864, 1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1900, 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936, 1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2051, 2055, 2059, 2063, 2067, 2071, 2075, 2079, 2083, 2087, 2091, 2095, 2099, 2103, 2107, 2111, 2115, 2119, 2123, 2127, 2131, 2135, 2139, 2143, 2147, 2151, 2155, 2159, 2163, 2167, 2171, 2175, 2179, 2183, 2187, 2191, 2195, 2199, 2203, 2207, 2211, 2215, 2219, 2223, 2227, 2231, 2235, 2239, 2243, 2247, 2251, 2255, 2259, 2263, 2267, 2271, 2275, 2279, 2282, 2286, 2290, 2294, 2298, 2302, 2306, 2310, 2314, 2318, 2322, 2326, 2330, 2334, 2338, 2341, 2345, 2349, 2353, 2357, 2361, 2365, 2369, 2373, 2377, 2381, 2384, 2388, 2392, 2396, 2400, 2404, 2408, 2412, 2415, 2419, 2423, 2427, 2431, 2435, 2439, 2442, 2446, 2450, 2454, 2458, 2462, 2466, 2469, 2473, 2477, 2481, 2485, 2488, 2492, 2496, 2500, 2504, 2508, 2511, 2515, 2519, 2523, 2526, 2530, 2534, 2538, 2542, 2545, 2549, 2553, 2557, 2560, 2564, 2568, 2572, 2575, 2579, 2583, 2587, 2590, 2594, 2598, 2601, 2605, 2609, 2612, 2616, 2620, 2624, 2627, 2631, 2635, 2638, 2642, 2646, 2649, 2653, 2657, 2660, 2664, 2667, 2671, 2675, 2678, 2682, 2686, 2689, 2693, 2696, 2700, 2704, 2707, 2711, 2714, 2718, 2721, 2725, 2729, 2732, 2736, 2739, 2743, 2746, 2750, 2753, 2757, 2760, 2764, 2767, 2771, 2774, 2778, 2781, 2785, 2788, 2792, 2795, 2799, 2802, 2806, 2809, 2813, 2816, 2819, 2823, 2826, 2830, 2833, 2837, 2840, 2843, 2847, 2850, 2854, 2857, 2860, 2864, 2867, 2870, 2874, 2877, 2880, 2884, 2887, 2890, 2894, 2897, 2900, 2904, 2907, 2910, 2914, 2917, 2920, 2923, 2927, 2930, 2933, 2936, 2940, 2943, 2946, 2949, 2953, 2956, 2959, 2962, 2965, 2969, 2972, 2975, 2978, 2981, 2984, 2988, 2991, 2994, 2997, 3000, 3003, 3006, 3010, 3013, 3016, 3019, 3022, 3025, 3028, 3031, 3034, 3037, 3040, 3044, 3047, 3050, 3053, 3056, 3059, 3062, 3065, 3068, 3071, 3074, 3077, 3080, 3083, 3086, 3089, 3092, 3095, 3098, 3100, 3103, 3106, 3109, 3112, 3115, 3118, 3121, 3124, 3127, 3130, 3132, 3135, 3138, 3141, 3144, 3147, 3150, 3152, 3155, 3158, 3161, 3164, 3167, 3169, 3172, 3175, 3178, 3181, 3183, 3186, 3189, 3192, 3194, 3197, 3200, 3203, 3205, 3208, 3211, 3213, 3216, 3219, 3222, 3224, 3227, 3230, 3232, 3235, 3238, 3240, 3243, 3245, 3248, 3251, 3253, 3256, 3259, 3261, 3264, 3266, 3269, 3271, 3274, 3277, 3279, 3282, 3284, 3287, 3289, 3292, 3294, 3297, 3299, 3302, 3304, 3307, 3309, 3312, 3314, 3317, 3319, 3322, 3324, 3327, 3329, 3331, 3334, 3336, 3339, 3341, 3344, 3346, 3348, 3351, 3353, 3355, 3358, 3360, 3362, 3365, 3367, 3370, 3372, 3374, 3376, 3379, 3381, 3383, 3386, 3388, 3390, 3393, 3395, 3397, 3399, 3402, 3404, 3406, 3408, 3411, 3413, 3415, 3417, 3419, 3422, 3424, 3426, 3428, 3430, 3433, 3435, 3437, 3439, 3441, 3443, 3445, 3448, 3450, 3452, 3454, 3456, 3458, 3460, 3462, 3464, 3467, 3469, 3471, 3473, 3475, 3477, 3479, 3481, 3483, 3485, 3487, 3489, 3491, 3493, 3495, 3497, 3499, 3501, 3503, 3505, 3507, 3509, 3511, 3513, 3515, 3517, 3519, 3521, 3523, 3525, 3526, 3528, 3530, 3532, 3534, 3536, 3538, 3540, 3542, 3543, 3545, 3547, 3549, 3551, 3553, 3555, 3556, 3558, 3560, 3562, 3564, 3565, 3567, 3569, 3571, 3573, 3574, 3576, 3578, 3580, 3581, 3583, 3585, 3587, 3588, 3590, 3592, 3594, 3595, 3597, 3599, 3600, 3602, 3604, 3606, 3607, 3609, 3611, 3612, 3614, 3616, 3617, 3619, 3621, 3622, 3624, 3625, 3627, 3629, 3630, 3632, 3633, 3635, 3637, 3638, 3640, 3641, 3643, 3645, 3646, 3648, 3649, 3651, 3652, 3654, 3655, 3657, 3658, 3660, 3662, 3663, 3665, 3666, 3668, 3669, 3671, 3672, 3674, 3675, 3676, 3678, 3679, 3681, 3682, 3684, 3685, 3687, 3688, 3690, 3691, 3692, 3694, 3695, 3697, 3698, 3699, 3701, 3702, 3704, 3705, 3706, 3708, 3709, 3710, 3712, 3713, 3715, 3716, 3717, 3719, 3720, 3721, 3723, 3724, 3725, 3726, 3728, 3729, 3730, 3732, 3733, 3734, 3736, 3737, 3738, 3739, 3741, 3742, 3743, 3744, 3746, 3747, 3748, 3749, 3751, 3752, 3753, 3754, 3756, 3757, 3758, 3759, 3760, 3762, 3763, 3764, 3765, 3766, 3768, 3769, 3770, 3771, 3772, 3773, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3869, 3870, 3871, 3872, 3873, 3874, 3874, 3875, 3876, 3877, 3878, 3878, 3879, 3880, 3881, 3882, 3882, 3883, 3884, 3885, 3885, 3886, 3887, 3888, 3889, 3889, 3890, 3891, 3892, 3892, 3893, 3894, 3895, 3895, 3896, 3897, 3898, 3898, 3899, 3900, 3901, 3901, 3902, 3903, 3903, 3904, 3905, 3906, 3906, 3907, 3908, 3908, 3909, 3910, 3910, 3911, 3912, 3912, 3913, 3914, 3915, 3915, 3916, 3917, 3917, 3918, 3919, 3919, 3920, 3921, 3921, 3922, 3922, 3923, 3924, 3924, 3925, 3926, 3926, 3927, 3928, 3928, 3929, 3929, 3930, 3931, 3931, 3932, 3933, 3933, 3934, 3934, 3935, 3936, 3936, 3937, 3937, 3938, 3939, 3939, 3940, 3940, 3941, 3941, 3942, 3943, 3943, 3944, 3944, 3945, 3945, 3946, 3947, 3947, 3948, 3948, 3949, 3949, 3950, 3950, 3951, 3952, 3952, 3953, 3953, 3954, 3954, 3955, 3955, 3956, 3956, 3957, 3957, 3958, 3958, 3959, 3959, 3960, 3960, 3961, 3962, 3962, 3963, 3963, 3964, 3964, 3965, 3965, 3965, 3966, 3966, 3967, 3967, 3968, 3968, 3969, 3969, 3970, 3970, 3971, 3971, 3972, 3972, 3973, 3973, 3974, 3974, 3975, 3975, 3975, 3976, 3976, 3977, 3977, 3978, 3978, 3979, 3979, 3979, 3980, 3980, 3981, 3981, 3982, 3982, 3983, 3983, 3983, 3984, 3984, 3985, 3985, 3985, 3986, 3986, 3987, 3987, 3988, 3988, 3988, 3989, 3989, 3990, 3990, 3990, 3991, 3991, 3992, 3992, 3992, 3993, 3993, 3994, 3994, 3994, 3995, 3995, 3995, 3996, 3996, 3997, 3997, 3997, 3998, 3998, 3998, 3999, 3999, 4000, 4000, 4000, 4001, 4001, 4001, 4002, 4002, 4002, 4003, 4003, 4004, 4004, 4004, 4005, 4005, 4005, 4006, 4006, 4006, 4007, 4007, 4007, 4008, 4008, 4008, 4009, 4009, 4009, 4010, 4010, 4010, 4011, 4011, 4011, 4012, 4012, 4012, 4013, 4013, 4013, 4013, 4014, 4014, 4014, 4015, 4015, 4015, 4016, 4016, 4016, 4017, 4017, 4017, 4017, 4018, 4018, 4018, 4019, 4019, 4019, 4020, 4020, 4020, 4020, 4021, 4021, 4021, 4022, 4022, 4022, 4022, 4023, 4023, 4023, 4024, 4024, 4024, 4024, 4025, 4025, 4025, 4025, 4026, 4026, 4026, 4026, 4027, 4027, 4027, 4028, 4028, 4028, 4028, 4029, 4029, 4029, 4029, 4030, 4030, 4030, 4030, 4031, 4031, 4031, 4031, 4032, 4032, 4032, 4032, 4033, 4033, 4033, 4033, 4034, 4034, 4034, 4034, 4034, 4035, 4035, 4035, 4035, 4036, 4036, 4036, 4036, 4037, 4037, 4037, 4037, 4037, 4038, 4038, 4038, 4038, 4039, 4039, 4039, 4039, 4039, 4040, 4040, 4040, 4040, 4040, 4041, 4041, 4041, 4041, 4042, 4042, 4042, 4042, 4042, 4043, 4043, 4043, 4043, 4043, 4044, 4044, 4044, 4044, 4044, 4045, 4045, 4045, 4045, 4045, 4046, 4046, 4046, 4046, 4046, 4047, 4047, 4047, 4047, 4047, 4047, 4048, 4048, 4048, 4048, 4048, 4049, 4049, 4049, 4049, 4049, 4049, 4050, 4050, 4050, 4050, 4050, 4050, 4051, 4051, 4051, 4051, 4051, 4052, 4052, 4052, 4052, 4052, 4052, 4053, 4053, 4053, 4053, 4053, 4053, 4054, 4054, 4054, 4054, 4054, 4054, 4054, 4055, 4055, 4055, 4055, 4055, 4055, 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4057, 4057, 4057, 4057, 4057, 4057, 4058, 4058, 4058, 4058, 4058, 4058, 4058, 4059, 4059, 4059, 4059, 4059, 4059, 4059, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4061, 4061, 4061, 4061, 4061, 4061, 4061, 4061, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4066, 4066, 4066, 4066, 4066, 4066, 4066, 4066, 4066, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4087, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4090, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4095};


const static uint8_t  TAB_state0 [5] [256] = {
  {1,   3,   4,   7,   8,   9,  11,  15,  16,  17,  18,  20,  21,  22,  26,  31,  32,  32,  32,  32,  34,  34,  34,  34,  34,  34,  36,  36,  36,  36,  38,  41,  42,  42,  44,  44,  46,  46,  48,  48,  50,  53,  54,  54,  56,  56,  58,  58,  60,  60,  62,  62,  50,  67,  68,  68,  70,  70,  72,  72,  74,  74,  76,  76,  62,  62,  64,  83,  84,  84,  86,  86,  44,  44,  58,  58,  60,  60,  76,  76,  78,  78,  80,  93,  94,  94,  96,  96,  48,  48,  88,  88,  80, 103, 104, 104, 106, 106,  62,  62,  88,  88,  80, 113, 114, 114, 116, 116,  62,  62,  88,  88,  90, 123, 124, 124, 126, 126,  62,  62,  98,  98,  90, 133, 134, 134, 136, 136,  62,  62,  98,  98,  90, 143, 144, 144,  68,  68,  62,  62,  98,  98, 100, 149, 150, 150, 108, 108, 100, 153, 154, 108, 100, 157, 158, 108, 100, 161, 162, 108, 110, 165, 166, 118, 110, 169, 170, 118, 110, 173, 174, 118, 110, 177, 178, 118, 110, 181, 182, 118, 120, 185, 186, 128, 120, 189, 190, 128, 120, 193, 194, 128, 120, 197, 198, 128, 120, 201, 202, 128, 120, 205, 206, 128, 120, 209, 210, 128, 130, 213, 214, 138, 130, 217, 218, 138, 130, 221, 222, 138, 130, 225, 226, 138, 130, 229, 230, 138, 130, 233, 234, 138, 130, 237, 238, 138, 130, 241, 242, 138, 130, 245, 246, 138, 140, 249, 250,  80, 140, 253, 254,  80, 140, 253, 254,  80},
  {2,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,  26,  28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62,  64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124,  94, 130,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 132, 124, 134,  92, 136, 124, 138,  92, 140, 124, 142,  92, 144, 124, 146,  92, 148, 124, 150,  92, 152, 124, 154,  92, 156, 124, 158,  92, 160, 124, 162,  92, 164, 124, 166,  92, 168, 120, 170,  92, 172, 120, 174,  92, 176, 120, 178,  92, 180, 120, 182,  92, 184, 120, 186,  92, 188, 120, 190,  92, 192, 120, 194,  88, 196, 120, 198,  88, 200, 120, 202,  88, 204, 120, 206,  88, 208, 120, 210,  88, 212, 120, 214,  88, 216, 120, 218,  88, 220, 120, 222,  88, 224, 120, 226,  88, 228, 120, 230,  88, 232, 120, 234,  88, 236, 120, 238,  88, 240, 120, 242,  88, 244, 120, 246,  88, 248, 120, 250,  88, 252, 120, 254,  88, 252, 120, 254,  88},
  {2,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,  26,  28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62,  64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 190, 192, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254},
  {1,  16,  17,  18,  38,  40,  42,  70,  46,  63,  95, 195, 159, 191, 223, 240,   2,  32,  33,  34,  39,  41,  43,  45,  47,  79, 111, 143, 175, 207, 225, 241,   3,  48,  49,  50,  36,  52,  53,  54,  55,  53,  57,  58,  59,  60,  61,  62,  19,  35,  36,  66,  67,  64,  54,  70,  71,  72,  73,  74,  75,  76,  77,  78,  68,  69,  37,  82,  83,  84,  80,  81,  87,  88,  89,   6,  91,  92,  93,  94,  85,  86,   4,  98,  99, 100, 101,  96,  97, 104, 105, 106, 107, 108, 109, 110, 102, 103,  20, 114, 115, 116, 117, 118, 112, 113,   6, 122, 123, 124, 125, 126, 119, 120,   5, 130, 131,  70, 133, 134, 135, 128,  97, 138, 139, 140, 141, 157, 136, 152,  21, 146, 147, 148, 149, 150, 151, 152,  97, 145, 155, 156, 157, 158, 168, 154,   6, 162, 163, 164, 165, 166, 167, 168, 149, 160, 161, 172, 173, 174, 170, 171,  22, 178, 179, 180, 181, 182, 183, 199, 185, 186, 176, 177, 189, 190, 187, 188,   7, 194, 195, 196, 197, 198, 199, 200, 201, 202, 195, 192, 226, 206, 204, 220,  23, 210, 211, 212, 213, 214, 149, 216, 217, 233, 219, 220, 208, 209, 221, 222,   8, 226, 227, 228, 229, 245, 231, 232, 233, 234, 235, 236, 226, 224, 238, 239,  24, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,  14, 253, 254, 255, 242,   9,  25,  10,  26,  11,  27,  12,  28,  13,  29,  14,  30,  15,  31},
  {2,  16,   4,  18,   6,  20,   8,  22,  10,  24,  12,  26,  14,  28, 128,  30,  18,  32,  20,  34,  22,  36,  24,  38,  26,  40,  28,  42,  30,  44, 130,  46,  34,  48,  36,  50,  38,  52,  40,  54,  42,  56,  44,  58,  46,  60,  24,  62,  50,  64,  52,  66,  54,  68,  56,  70,  58,  72,  60,  74,  62,  76,  40,  78,  66,  80,  68,  82,  70,  84,  72,  86,  74,  88,  76,  90,  78,  92,  40,  94,  82,  96,  84,  98,  86, 100,  88, 102,  90, 104,  92, 106,  94, 108,  56, 110,  98, 112, 100, 114, 102, 116, 104, 118, 106, 120, 108, 122, 110, 124,  56, 126, 114, 112, 116, 114, 118,  66, 120,  66, 122,  68, 124,  68, 126,  70,  72,  70, 132, 112, 134, 114, 136, 112, 138, 114, 140, 112, 142, 114, 144, 112, 146, 114, 148, 112, 150, 114, 152, 112, 154, 114, 156, 112, 158, 114, 160, 112, 162, 114, 164, 112, 166, 114, 168, 112, 170, 114, 172, 112, 174, 114, 176, 112, 178, 114, 180, 112, 182, 114, 184, 112, 186, 114, 188, 112, 190, 114, 192, 112, 194, 114, 196, 112, 198, 114, 200, 112, 202, 114, 204, 112, 206, 114, 208, 112, 210, 114, 212, 112, 214, 114, 216, 112, 218, 114, 220, 112, 222, 114, 224, 112, 226, 114, 228, 112, 230, 114, 232, 112, 234, 114, 236, 112, 238, 114, 240, 112, 242, 114, 244, 112, 246, 114, 248, 112, 250, 114, 252, 112, 254, 114, 252, 112, 254, 114}
};


const static uint8_t  TAB_state1 [5] [256] = {
  {2,   5,   6,  10,  12,  13,  14,  19,  23,  24,  25,  27,  28,  29,  30,  33,  35,  35,  35,  35,  37,  37,  37,  37,  37,  37,  39,  39,  39,  39,  40,  43,  45,  45,  47,  47,  49,  49,  51,  51,  52,  43,  57,  57,  59,  59,  61,  61,  63,  63,  65,  65,  66,  55,  57,  57,  73,  73,  75,  75,  77,  77,  79,  79,  81,  81,  82,  69,  71,  71,  73,  73,  59,  59,  61,  61,  49,  49,  89,  89,  91,  91,  92,  69,  87,  87,  45,  45,  99,  99, 101, 101, 102,  69,  87,  87,  57,  57, 109, 109, 111, 111, 112,  85,  87,  87,  57,  57, 119, 119, 121, 121, 122,  85,  97,  97,  57,  57, 129, 129, 131, 131, 132,  85,  97,  97,  57,  57, 139, 139, 141, 141, 142,  95,  97,  97,  57,  57,  81,  81, 147, 147, 148,  95, 107, 107, 151, 151, 152,  95, 107, 155, 156,  95, 107, 159, 160, 105, 107, 163, 164, 105, 117, 167, 168, 105, 117, 171, 172, 105, 117, 175, 176, 105, 117, 179, 180, 115, 117, 183, 184, 115, 127, 187, 188, 115, 127, 191, 192, 115, 127, 195, 196, 115, 127, 199, 200, 115, 127, 203, 204, 115, 127, 207, 208, 125, 127, 211, 212, 125, 137, 215, 216, 125, 137, 219, 220, 125, 137, 223, 224, 125, 137, 227, 228, 125, 137, 231, 232, 125, 137, 235, 236, 125, 137, 239, 240, 125, 137, 243, 244, 135, 137, 247, 248, 135,  69, 251, 252, 135,  69, 255, 252, 135,  69, 255},
  {3,   3,   5,   7,   9,  11,  13,  15,  17,  19,  21,  23,  25,  27,  29,  31,  33,  35,  37,  39,  41,  43,  45,  47,  49,  51,  53,  55,  57,  59,  61,  63,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,  93,  95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,  93,  95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 131,  97,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,  93,  95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 129,  67, 133,  99, 135,  67, 137,  99, 139,  67, 141,  99, 143,  67, 145,  99, 147,  67, 149,  99, 151,  67, 153,  99, 155,  67, 157,  99, 159,  67, 161,  99, 163,  67, 165,  99, 167,  71, 169,  99, 171,  71, 173,  99, 175,  71, 177,  99, 179,  71, 181,  99, 183,  71, 185,  99, 187,  71, 189,  99, 191,  71, 193, 103, 195,  71, 197, 103, 199,  71, 201, 103, 203,  71, 205, 103, 207,  71, 209, 103, 211,  71, 213, 103, 215,  71, 217, 103, 219,  71, 221, 103, 223,  71, 225, 103, 227,  71, 229, 103, 231,  71, 233, 103, 235,  71, 237, 103, 239,  71, 241, 103, 243,  71, 245, 103, 247,  71, 249, 103, 251,  71, 253, 103, 255,  71, 253, 103, 255},
  {3,   3,   5,   7,   9,  11,  13,  15,  17,  19,  21,  23,  25,  27,  29,  31,  33,  35,  37,  39,  41,  43,  45,  47,  49,  51,  53,  55,  57,  59,  61,  63,  65,  67,  69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,  93,  95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 191, 193, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255},
  {51, 66,  52,   4,  40, 116,  97,  75,  47,  79, 141, 188, 250, 238, 137, 212,  37,  67,  38,  85, 130, 102,  89,  61,   9, 110, 172, 219, 207, 240, 182, 227,  82,  70, 100, 130,  41,  84,  55,  21, 131, 117, 103, 104,  90,  76,  62,  63,  80, 115,  21,  65,  99,  70,  41, 146, 132, 118, 112, 105,  91,  77,  78,  94,  80,  56,  69, 114,  85,  71,   6, 147, 133, 119, 113, 106,  92,  93, 109, 125,  42, 162,   5, 100,  81,  57,  22, 148, 134, 120, 121, 107, 108, 124, 140, 156, 163, 149, 115,  86,  72,  43, 178, 164, 135, 128, 122, 123, 139, 155, 161, 176, 150, 136, 101,  87,  58,   7, 179, 165, 151, 129, 138, 145, 160, 171, 187, 203, 137, 144,  96,  73,  44, 194, 180, 166, 152, 153, 154, 170, 186, 202, 218, 234, 169, 185,  88,  59,  23, 195, 181, 167, 168, 184, 200, 201, 217, 233, 249,  13, 216, 232,  74,  45, 210, 196, 182, 183, 199, 215, 231, 247, 248,  28, 191, 209,  12, 175,  60,   8, 211, 197, 198, 214, 230, 246,  27, 159, 190, 206, 222, 253, 208, 237,  46, 226, 212, 213, 229, 245,  11, 143, 174, 193, 221, 252,  30, 255, 225,  31,  24, 227, 228, 244,  26, 127, 158, 189, 205, 236,  14, 239, 241, 152, 152, 182, 242, 243,  10, 111, 142, 173, 192, 220, 251, 223, 254, 237, 167, 197, 212, 242,  25,  95, 126, 157, 177, 204, 235,  29, 224,  15, 252, 167, 197, 227},
  {1,  17,   3,  19,   5,  21,   7,  23,   9,  25,  11,  27,  13,  29,  15,  31,  19,  33,  21,  35,  23,  37,  25,  39,  27,  41,  29,  43,  31,  45,  31,  47,  35,  49,  37,  51,  39,  53,  41,  55,  43,  57,  45,  59,  47,  61,  25,  63,  51,  65,  53,  67,  55,  69,  57,  71,  59,  73,  61,  75,  63,  77,  25,  79,  67,  81,  69,  83,  71,  85,  73,  87,  75,  89,  77,  91,  79,  93,  41,  95,  83,  97,  85,  99,  87, 101,  89, 103,  91, 105,  93, 107,  95, 109,  41, 111,  99, 113, 101, 115, 103, 117, 105, 119, 107, 121, 109, 123, 111, 125,  57, 127, 115, 129, 117, 131, 119,  67, 121,  69, 123,  69, 125,  71, 127,  71,  57,  73,  15, 133,  31, 135,  15, 137,  31, 139,  15, 141,  31, 143,  15, 145,  31, 147,  15, 149,  31, 151,  15, 153,  31, 155,  15, 157,  31, 159,  15, 161,  31, 163,  15, 165,  31, 167,  15, 169,  31, 171,  15, 173,  31, 175,  15, 177,  31, 179,  15, 181,  31, 183,  15, 185,  31, 187,  15, 189,  31, 191,  15, 193,  31, 195,  15, 197,  31, 199,  15, 201,  31, 203,  15, 205,  31, 207,  15, 209,  31, 211,  15, 213,  31, 215,  15, 217,  31, 219,  15, 221,  31, 223,  15, 225,  31, 227,  15, 229,  31, 231,  15, 233,  31, 235,  15, 237,  31, 239,  15, 241,  31, 243,  15, 245,  31, 247,  15, 249,  31, 251,  15, 253,  31, 255,  15, 253,  31, 255}
};



typedef struct {
    uint32_t *t_ctx;  // Context of last prediction
    uint32_t *t;
    uint32_t *t_base; // ctx -> prediction in high 22 bits, count in low 10 bits
    uint32_t  limit;
} StateMap_t;

static size_t stateMapInit (StateMap_t *p_sm, uint32_t limit_in, uint32_t n) {
    size_t n_allocate_bytes;
    p_sm->limit = limit_in;
    MEM_ALLOC(uint32_t, p_sm->t_base, n, 0x80000000U, n_allocate_bytes);
    p_sm->t_ctx = p_sm->t = p_sm->t_base;
    return n_allocate_bytes;
}

static void stateMapFree (StateMap_t *p_sm) {
    free(p_sm->t_base);
}
    
static uint32_t stateMapPred (StateMap_t *p_sm, uint32_t bit20, uint32_t cx) {
    uint32_t i    = (*p_sm->t_ctx) & 0x3FFU;  // count
    uint32_t prob = (*p_sm->t_ctx) >> 12;     // prediction
    (*p_sm->t_ctx) += (i < p_sm->limit);
    (*p_sm->t_ctx) += ((bit20-prob) * TAB_DT(i)) & 0xfffffc00U;
    p_sm->t_ctx = p_sm->t + cx;
    return ( (*(p_sm->t_ctx)) >> 20 );
}

static void stateMapMove (StateMap_t *p_sm, int32_t i) {
    p_sm->t += (i << 8);
}



typedef struct {
    uint32_t  ctx;      // Context of last prediction
    uint32_t *t_base;   // ctx -> prediction in high 22 bits, count in low 10 bits
    uint32_t  limit;
} SecondaryEstimator_t; // Secondary Symbol Estimation (SSE)

static size_t secondaryEstimitorInit (SecondaryEstimator_t *p_sse, uint32_t limit_in, uint32_t n) {
    uint32_t i;
    size_t n_allocate_bytes;
    p_sse->limit = limit_in;
    p_sse->ctx = 0;
    MEM_ALLOC(uint32_t, p_sse->t_base, n, 0, n_allocate_bytes);
    for (i=0; i<n; i++) {
        uint32_t p = ((i%24*2+1)*4096) / 48 - 1;
        p_sse->t_base[i] = (((uint32_t)(TAB_squash[p])) << 20) + 12;
    }
    return n_allocate_bytes;
}

static void secondaryEstimitorFree (SecondaryEstimator_t *p_sse) {
    free(p_sse->t_base);
}

static uint32_t secondaryEstimitorMap (SecondaryEstimator_t *p_sse, uint32_t bit20, uint32_t prob, uint32_t cx) {
    uint32_t i   = p_sse->t_base[p_sse->ctx] & 1023; // count
    uint32_t ppr = p_sse->t_base[p_sse->ctx] >> 12;  // prediction
    uint32_t wt  = prob & 0xfffU;                    // interpolation weight of next element
    p_sse->t_base[p_sse->ctx] += (i<p_sse->limit);
    p_sse->t_base[p_sse->ctx] += ((bit20-ppr) * TAB_DTA(i) + 0x200) & 0xfffffc00U;
    cx = cx*24 + (prob>>12);
    p_sse->ctx = cx+(wt>>11);
    prob= (((p_sse->t_base[cx]>>13)*(0x1000-wt)+(p_sse->t_base[cx+1]>>13)*wt)>>19);
    return prob;
}



static uint32_t  hash1 (uint32_t i) {  i*=0xfffefdfb; i=RORi(i,10); return (i*765432197); }
static uint32_t  hash2 (uint32_t i) {  i*=0xfffefdfb; i=RORi(i,13); return (i*654321893); }
static uint32_t  hash3 (uint32_t i) {  i*=0xfffefdfb; i=RORi(i,11); return (i*543210973); }
static uint32_t  hash4 (uint32_t i) {  i*=0xfffefdfb; i=RORi(i,12); return (i*432109879); }
static uint32_t  hash5 (uint32_t i) {  i*=987654323;  i=RORi(i,11); return (i*234567891); }
static uint32_t  hash6 (uint32_t i) {  i*=0xfeff77ff; i=RORi(i,13); return (i*876543211); }
static uint32_t  hash7 (uint32_t i) {  i*=0xfeff77ff; i=RORi(i,12); return (i          ); }
static uint32_t  hash8 (uint32_t i) {                 i=RORi(i,14); return (i*654321893); }
static uint32_t  hash9 (uint32_t i) {  i*=0xfeff77ff; i=RORi(i,10); return (i*543210973); }
static uint32_t  hash0 (uint32_t i) {                 i=RORi(i,14); return (i*432109879); }
static uint32_t hash3a (uint32_t i) {                 i=RORi(i,10); return (i*543210973); }



typedef struct {
    uint8_t *t_base;
    uint8_t *t;       // table: 1 element = B bytes: checksum,priority,data,data,...
    uint32_t B;
    uint32_t NB;      // size in bytes
} HashTable_t;        // 

static size_t hashTableInit (HashTable_t *p_ht, uint32_t n) {
    size_t n_allocate_bytes;
    p_ht->B  = 16;
    p_ht->NB = n - p_ht->B;
    MEM_ALLOC(uint8_t, p_ht->t_base, (n+0x400), 0, n_allocate_bytes);
    p_ht->t  = p_ht->t_base + 0x1FF;
    p_ht->t -= (0x1FF & (size_t)p_ht->t); // align on cache line (512B)
    return n_allocate_bytes;
}

static void hashTableFree (HashTable_t *p_ht) {
    free(p_ht->t_base);
}

static uint8_t *hashTableGet (HashTable_t *p_ht, uint32_t hsh) {
    uint8_t *p, *q, *r;
    p = p_ht->t + ((hsh*p_ht->B)&p_ht->NB);
    q = p + p_ht->B;
    r = p + p_ht->B * 2;
    hsh >>= 24;
    if (*p == (uint8_t)hsh) return p + 1;
    if (*q == (uint8_t)hsh) return q + 1;
    if (*r == (uint8_t)hsh) return r + 1;
    if (*(p+1) > *(q+1)) p = q;
    if (*(p+1) > *(r+1)) p = r;
    ((uint32_t*)p)[0] = hsh;
    ((uint32_t*)p)[1] = 0;
    ((uint32_t*)p)[2] = 0;
    ((uint32_t*)p)[3] = 0;
    return p + 1;
}



typedef struct {
    uint32_t len2ctx  [MAXLEN+1] [2];
    uint32_t len2order[MAXLEN+1];
    uint32_t pos;
    uint8_t *buf;            // input buffer
    uint32_t h1, h2, h3;     // context hashes
    uint32_t HN, N;          // last hash table index, n/8-1
    uint32_t *ht;            // context hash -> next byte in buf
    uint32_t match;          // pointer to current byte in matched context in buf
    uint32_t buf_match;      // buf[match]+256
    uint32_t len;            // length of match
} MatchModel_t;              // 

static void matchModelSearch (MatchModel_t *p_mm, uint32_t hsh) {
    p_mm->len = 1;        
    p_mm->match = p_mm->ht[hsh];    
    if (p_mm->match != p_mm->pos) {
        while (p_mm->len<MAXLEN+1 && p_mm->buf[(p_mm->match-p_mm->len)&p_mm->N]==p_mm->buf[(p_mm->pos-p_mm->len)&p_mm->N]) {
            p_mm->len ++;
        }
    }
}

static uint8_t *matchModelSearch2 (MatchModel_t *p_mm, uint32_t hsh, uint8_t *p1, uint8_t *p2) {
    p_mm->len   = 1;
    p_mm->match = p_mm->ht[hsh];    
    if (p_mm->match != p_mm->pos) {
        p2 = p1;        
        while (p_mm->len<MAXLEN+1 && p_mm->buf[(p_mm->match-p_mm->len)&p_mm->N] == *p2) {
            p_mm->len ++;
            p2 --;
        }            
    }
    return p2;
}

static size_t matchModelInit (MatchModel_t *p_mm, uint32_t n, uint32_t method) {    // n must be a power of 2 at least 8.
    //assert(n>=8 && (n&n-1)==0);
    size_t n_allocate_bytes;
    uint32_t i;
    p_mm->N  = n/2-1;
    p_mm->HN = n/8-1;
    p_mm->match = p_mm->len = 0;
    p_mm->h1 = p_mm->h2 = p_mm->h3 = 0;
    p_mm->pos = 0;
    for (i=1; i<=MAXLEN; i++) {
        uint32_t ctx = TAB_len2ctx[i] * 512U;
        p_mm->len2ctx[i][0] = ctx;
        p_mm->len2ctx[i][1] = ctx - 256;
        
        if (method == METHOD_TEXT)
            p_mm->len2order[i] = MI * (5+(i>=10)+(i>=14)+(i>=19)+(i>28))     ;
        else
            p_mm->len2order[i] = MI * (5+(i>=8) +(i>=12)+(i>=18)+(i==MAXLEN));
    }
    MEM_ALLOC(uint32_t, p_mm->ht, p_mm->HN+1+p_mm->N+1, 0, n_allocate_bytes);
    p_mm->buf = (uint8_t*)(p_mm->ht + (p_mm->HN+1));
    return n_allocate_bytes;
}

static void matchModelFree (MatchModel_t *p_mm) {
    free(p_mm->ht);
}

static uint32_t matchModelPred (MatchModel_t *p_mm, uint32_t c_dec, uint32_t c_nibbles, int32_t k) {  // predict next bit to m
    if (p_mm->len > 0) {
        uint32_t b = p_mm->buf_match >> k;
        if ((b>>1) == c_dec) {
            b &= 1;    // next bit
            c_dec = p_mm->len2ctx[p_mm->len][b] + c_nibbles;
        } else {
            p_mm->len = 0;
        }
    }
    return c_dec;
}

static uint32_t matchModelGetOffset (MatchModel_t *p_mm, uint32_t c1, uint32_t c2, uint32_t c3, uint32_t c4) {
    uint32_t offset = p_mm->len;
    if (offset != 0) {
        offset = p_mm->len2order[offset];
    } else if (c1 != 0) {
        offset = MI;
        if (c2 != 0) {
            offset += MI;
            if (c3 != 0) {
                offset += MI;
                if (c4 != 0)
                    offset += MI;
            }
        }
    }
    return offset;
}

static void matchModelUpdate (MatchModel_t *p_mm, uint32_t c, uint32_t c4, uint32_t c8, uint32_t cc) {
    p_mm->buf[p_mm->pos] = (uint8_t)c;
    p_mm->pos = (p_mm->pos+1) & p_mm->N;
    p_mm->h1 = (p_mm->h1*(7<<1)-c-1)    & p_mm->HN;
    p_mm->h2 = (c4*1021-c8*2039+cc*421) & p_mm->HN;
    p_mm->h3 = hash3a(c4*59+c8*383)     & p_mm->HN;
    if (p_mm->len > MINLEN) {
        p_mm->match ++;
        p_mm->match &= p_mm->N;
        if (p_mm->len < MAXLEN)
            p_mm->len ++;
    } else {
        if (p_mm->pos >= MAXLEN) {
            uint8_t *p1 = p_mm->buf + p_mm->pos - 1;
            uint8_t *p2 = NULL;
            p2 = matchModelSearch2(p_mm, p_mm->h1, p1, p2);
            if (p_mm->len < 4) {
                p2 = matchModelSearch2(p_mm, p_mm->h2, p1, p2);
                if (p_mm->len<4)
                    p2 = matchModelSearch2(p_mm, p_mm->h3, p1, p2);
            }
        } else {
            matchModelSearch(p_mm, p_mm->h1);
            if (p_mm->len < 4) {
                matchModelSearch(p_mm, p_mm->h2);
                if (p_mm->len < 4) {
                    matchModelSearch(p_mm, p_mm->h3);
                }
            }
        }
        p_mm->len --;
    }
    p_mm->buf_match = p_mm->buf[p_mm->match] + 256U;
    p_mm->ht[p_mm->h1] = p_mm->ht[p_mm->h2] = p_mm->ht[p_mm->h3] = p_mm->pos;  // update index
}

static uint32_t matchModelPosCond (MatchModel_t *p_mm, uint32_t dpsft) {
    if ((p_mm->pos & (256*1024-1)) == 0)
        if ( (p_mm->pos== 9*512*1024 && dpsft==16) || (p_mm->pos==1024*1024 && dpsft==15) || dpsft==14 )
            return 1;
    return 0;
}



typedef struct {
    uint8_t *p_buf;
    uint8_t *p_limit;
    uint32_t is_compress; // 1:compress   0:decompress
    uint32_t x1, x2;      // Range, initially [0, 1), scaled by 2^32
    uint32_t x;           // Decompress mode: last 4 input bytes of p_buf
} AriCodec_t;

static int ariCodecRW (AriCodec_t *p_ac) {
    if (p_ac->is_compress) {
        RET_ERR_IF(R_ERR_OUTPUT_OVERFLOW, (p_ac->p_buf >= p_ac->p_limit));
        *(p_ac->p_buf++) = (uint8_t)(p_ac->x1 >> 24);
    } else {
        p_ac->x <<= 8;
        if (p_ac->p_buf < p_ac->p_limit) {
            p_ac->x += *(p_ac->p_buf++);
        } else {
            p_ac->x += 0xFF;
        }
    }
    return R_OK;
}

static int ariCodecInit (AriCodec_t *p_ac, uint32_t is_compress_in, uint8_t *p_buf_in, size_t buf_len) {
    p_ac->is_compress = is_compress_in;
    p_ac->p_buf   = p_buf_in;
    p_ac->p_limit = p_buf_in + buf_len;
    p_ac->x1 = 0;
    p_ac->x2 = 0xffffffff;
    p_ac->x  = 0;
    if (!p_ac->is_compress) {  // let x = first 4 bytes of p_buf
        RET_WHEN_ERR(ariCodecRW(p_ac));
        RET_WHEN_ERR(ariCodecRW(p_ac));
        RET_WHEN_ERR(ariCodecRW(p_ac));
        RET_WHEN_ERR(ariCodecRW(p_ac));
    }
    return R_OK;
}

static int ariCodecBit (AriCodec_t *p_ac, uint32_t *p_bit, uint32_t prob) {
    uint32_t xmid = p_ac->x2 - p_ac->x1;
    xmid = p_ac->x1 + (xmid >> 12) * prob + ((xmid & 0xfff) * prob >> 12);
    if (!p_ac->is_compress) {
        *p_bit = (p_ac->x<=xmid) ? 1U : 0U;
    }
    if (*p_bit) {
        p_ac->x2 = xmid;
    } else {
        p_ac->x1 = xmid + 1;
    }
    while (((p_ac->x1 ^ p_ac->x2) & 0xff000000) == 0) {  // pass equal leading bytes of range
        RET_WHEN_ERR(ariCodecRW(p_ac));
        p_ac->x1 <<= 8;
        p_ac->x2 <<= 8;
        p_ac->x2  += 0xFF;
    }
    return R_OK;
}

static int ariCodecFlush (AriCodec_t *p_ac) {
    if (p_ac->is_compress) {
        RET_WHEN_ERR(ariCodecRW(p_ac));
    }
    return R_OK;
}



typedef struct {
    int32_t  *TAB_stretch;  // initialized when LPAQ8_Codec is created, and will not be modified
    uint32_t *TAB_stretch2; // initialized when LPAQ8_Codec is created, and will not be modified
    uint32_t *TAB_squash2;  // initialized when LPAQ8_Codec is created, and will not be modified
    uint32_t *TAB_fail3;    // initialized when LPAQ8_Codec is created, and will not be modified
    uint8_t  *TAB_fail2;    // initialized when LPAQ8_Codec is created, and will not be modified
    int32_t *mxr_wx;        // MI*MC weights
    uint32_t method;
    AriCodec_t ari_codec;
    HashTable_t          t1, t2, t3;                        // ctx -> state
    StateMap_t           sm0, sm1, sm2, sm3, sm4, sm5, sm6; // 6 general proposed predictors
    SecondaryEstimator_t sse1, sse2;
    MatchModel_t         mm;                                // predicts next bit by matching context
    uint8_t *tbase;                                         // order 1 ctx -> state
    uint32_t first_bit;
    uint32_t c4, c8, cc;
    uint32_t h5, pw;
    uint32_t fail3;
    uint8_t  fail2;
    uint32_t dpsft;
} lpaq8Codec_t;

static uint32_t mxr_dot_product (uint32_t dpsft, int32_t *mxr_tx, int32_t *mxr_ctx) {
    int32_t sum = 0, i;
    for (i=0; i<=6; i++) {
        sum += mxr_tx[i] * mxr_ctx[i];
    }
    sum += mxr_ctx[7] << 8;
    sum >>= dpsft;
    sum += 2047;
    return (uint32_t)CLIP(sum, 0, 4094);
}

static uint8_t mxr_update (uint8_t *TAB_fail2, int32_t *mxr_tx, int32_t *mxr_ctx, uint32_t bit, uint32_t pr0) {  // Adjust weights to minimize coding cost of last prediction
    int32_t err = ((int32_t)bit) * 0xfff - (int32_t)pr0;
    if (err >= MXR_UPD || err <= -MXR_UPD) {
        int32_t e = err * MXR_MUL / MXR_DIV;
        //assert(e>=-32768 && e<32768);
        mxr_ctx[0] += (mxr_tx[0]*e+0x0800) >> 12;
        mxr_ctx[1] += (mxr_tx[1]*e+0x0800) >> 12;
        mxr_ctx[2] += (mxr_tx[2]*e+0x1000) >> 13;
        mxr_ctx[3] += (mxr_tx[3]*e+0x0800) >> 12;
        mxr_ctx[4] += (mxr_tx[4]*e+0x0800) >> 12;
        mxr_ctx[5] += (mxr_tx[5]*e+0x0800) >> 12;
        mxr_ctx[6] += (mxr_tx[6]*e+0x0800) >> 12;
        mxr_ctx[7] += (          e+4     ) >> 3;
        return TAB_fail2[err+4096];
    } else {
        return 0;
    }
}

static void act_sse (lpaq8Codec_t *p_lpaq, uint32_t *p_pr0, uint32_t *p_pr1, uint32_t bit20, uint32_t c_2bytes) {
    uint32_t prob = *p_pr0;
    uint32_t aprob = secondaryEstimitorMap(&p_lpaq->sse1, bit20, prob*23, c_2bytes);
    *p_pr0 = prob = ((p_lpaq->TAB_squash2[prob] + 3*aprob) >> 2);
    aprob = secondaryEstimitorMap(&p_lpaq->sse2, bit20, p_lpaq->TAB_stretch2[prob], p_lpaq->fail3 + p_lpaq->fail2);
    prob = (prob*5 + 11*aprob+8) >> 4;
    *p_pr1 = prob + (prob<2048);
}

static void upd_cp (uint32_t bit, uint32_t nibble, uint8_t *cp1, uint8_t *cp2, uint8_t *cp3, uint8_t *cp4, uint8_t *cp5, uint8_t *cp6, uint32_t m2, uint32_t m3, uint32_t m4, uint32_t m5) {
    const uint8_t (*tab)[256] = bit ? TAB_state1 : TAB_state0;
    if (nibble) {
        *cp6 = tab[1][*cp6];
    }
    *cp1 = tab[0][*cp1];
    *cp2 = tab[m2][*cp2];
    *cp3 = tab[m3][*cp3];
    *cp4 = tab[m4][*cp4];
    *cp5 = tab[m5][*cp5];
    if (!nibble) {
        *cp6 = tab[1][*cp6];
    }
}

static void upd_sm_cp (lpaq8Codec_t *p_lpaq, uint32_t bit, int32_t k, uint8_t *cp1, uint8_t *cp2, uint8_t *cp3, uint8_t *cp4, uint8_t *cp5, uint8_t *cp6) {
    switch (k) {
        case 7 : 
            stateMapMove(&p_lpaq->sm4, 1);
            stateMapMove(&p_lpaq->sm5, 1);
            stateMapMove(&p_lpaq->sm6, 1);
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 0,3,4,2);
            break;
        case 6 :
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 0,3,0,1);
            break;
        case 5 :
            stateMapMove(&p_lpaq->sm2, 1);
            stateMapMove(&p_lpaq->sm4, ((p_lpaq->method==METHOD_TEXT) ? 1 : 0));
            stateMapMove(&p_lpaq->sm5, 1);
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 0,3,0,1);
            break;
        case 4 :
            stateMapMove(&p_lpaq->sm1, 1);
            upd_cp(bit, 1, cp1, cp2, cp3, cp4, cp5, cp6, 1,3,0,1);
            break;
        case 3 :
            stateMapMove(&p_lpaq->sm6, 1);
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 1,3,0,1);
            break;
        case 2 :
            stateMapMove(&p_lpaq->sm3, 1);
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 1,3,0,1);
            break;
        case 1 :
            upd_cp(bit, 0, cp1, cp2, cp3, cp4, cp5, cp6, 1,2,0,1);
            break;
        default :  // case 0:
            stateMapMove(&p_lpaq->sm1, -1);
            stateMapMove(&p_lpaq->sm2, -1);
            stateMapMove(&p_lpaq->sm3, -1);
            stateMapMove(&p_lpaq->sm4, ((p_lpaq->method==METHOD_TEXT) ? -2 : -1));
            stateMapMove(&p_lpaq->sm5, -2);
            stateMapMove(&p_lpaq->sm6, -2);
            upd_cp(bit, 1, cp1, cp2, cp3, cp4, cp5, cp6, 1,2,0,1);
            break;
    }
}

static uint8_t exchange_for_text (uint8_t c, uint32_t method) {
    if (method == METHOD_TEXT) {
        if      (c == 0x20)
            c = 0x1F;
        else if (c == 0x1F)
            c = 0x20;
    }
    return c;
}

static int lpaq8CodecByte (lpaq8Codec_t *p_lpaq, uint8_t c_enc, uint8_t *p_c_dec) {
    uint32_t  c_nibbles  = ((p_lpaq->c4 << 1) & 0xF0) | ((p_lpaq->c4 >> 11) & 0x0F);
    uint32_t  c_lastbyte = ((p_lpaq->c4 & 0xFF) << 8);
    int32_t   c4i   = (int32_t)p_lpaq->c4;
    uint32_t  bit   = p_lpaq->c4 & 1;
    uint32_t  c_dec = 1;
    uint8_t  *cp1, *cp2, *cp3, *cp4, *cp5, *cp6, *cp6_base;
    int32_t  *mxr_base = p_lpaq->mxr_wx;
    int32_t  k;
    
    c_enc = exchange_for_text(c_enc, p_lpaq->method);
    
    cp6_base = p_lpaq->tbase + ((p_lpaq->c4 & 0xF0) + ((p_lpaq->c4>>12) & 0xC) + ((p_lpaq->c4>>22) & 0x3)) * 256;
    cp1 = cp2 = cp3 = cp4 = cp5 = cp6 = p_lpaq->tbase;
    
    for (k=7; k>=0; k--) {
        uint32_t  pr0 = 2048;
        uint32_t  pr1 = 2048;
        int32_t  *mxr_ctx = mxr_base;
        int32_t   mxr_tx [MI];
        
        mxr_tx[0] = mxr_tx[1] = mxr_tx[2] = mxr_tx[3] = mxr_tx[4] = mxr_tx[5] = mxr_tx[6] = mxr_tx[7] = 0;
        
        if (!p_lpaq->first_bit) {
            if (k == 7) {
                cp1 = hashTableGet(&p_lpaq->t1, hash1( (uint32_t)(c4i&0xffff)*8191 ));
                cp2 = hashTableGet(&p_lpaq->t1, hash2( (uint32_t)(c4i&0x00ffffff) ));
                cp3 = hashTableGet(&p_lpaq->t2, hash3( (uint32_t)(c4i*127) ));
                cp4 = hashTableGet(&p_lpaq->t3, hash4( (uint32_t)(c4i*197-(p_lpaq->c8 & 0xffff)*59999) ));
                cp5 = hashTableGet(&p_lpaq->t2, hash5( p_lpaq->h5 - p_lpaq->pw ));
                
                mxr_base = p_lpaq->mxr_wx + MI * 10 * 8 * ( ((c4i>>6)&0x3) + ((c4i>>12)&0xC) );
                
            } else if (k == 3) {
                cp1 = hashTableGet(&p_lpaq->t1, hash6( c_dec - ((c4i&0xffff)*8191) ));
                cp2 = hashTableGet(&p_lpaq->t1, hash7( c_dec*23-(c4i&0x00ffffff)*251 ));
                cp3 = hashTableGet(&p_lpaq->t2, hash8( c_dec   - c4i*59 ));
                cp4 = hashTableGet(&p_lpaq->t3, hash9( c_dec*31- c4i*197+(p_lpaq->c8 & 0xffff)*63331 ));       
                cp5 = hashTableGet(&p_lpaq->t2, hash0( c_dec*P5_MUL-p_lpaq->h5 ));
                
                mxr_base = (p_lpaq->mxr_wx + MI*40 + MI*10*8*(((c4i>>6)&3)+(c_dec&12)));  
                
            } else {
                uint32_t step = (bit+1) << (2-(k&3));  // (2-(k&3)) = 0,1,2
                
                cp1 += step;
                cp2 += step;
                cp3 += step;
                cp4 += step;
                cp5 += step;
                
                mxr_base += MI*10;
            }
            
            cp6 = cp6_base + c_dec;
            
            {
                uint32_t bit20 = (bit<<20);
                uint32_t ct0 = matchModelPred(&p_lpaq->mm, c_dec, c_nibbles, k);
                
                mxr_tx[0] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm0, bit20,  ct0) ];
                mxr_tx[1] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm1, bit20, *cp1) ];
                mxr_tx[2] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm2, bit20, *cp2) ];
                mxr_tx[3] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm3, bit20, *cp3) ];
                mxr_tx[4] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm4, bit20, *cp4) ];
                mxr_tx[5] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm5, bit20, *cp5) ];
                mxr_tx[6] = p_lpaq->TAB_stretch[ stateMapPred(&p_lpaq->sm6, bit20, *cp6) ];
                
                mxr_ctx = mxr_base + matchModelGetOffset(&p_lpaq->mm, *cp1, *cp2, *cp3, *cp4); 
                
                pr0 = mxr_dot_product(p_lpaq->dpsft, mxr_tx, mxr_ctx);
                
                act_sse(p_lpaq, &pr0, &pr1, bit20, (c_lastbyte+c_dec));
            }
        }
        
        p_lpaq->first_bit = 0;
        
        bit = (uint32_t)((c_enc >> k) & 1);
        
        RET_WHEN_ERR( ariCodecBit(&p_lpaq->ari_codec, &bit, pr1) );
        
        c_dec = (c_dec<<1) | bit;
        
        upd_sm_cp(p_lpaq, bit, k, cp1, cp2, cp3, cp4, cp5, cp6);
        
        {
            uint8_t fail = mxr_update(p_lpaq->TAB_fail2, mxr_tx, mxr_ctx, bit, pr0);
            if (k != 0) {
                p_lpaq->fail2 <<= 1;
                p_lpaq->fail2  |= fail;
            } else {
                p_lpaq->fail3   = p_lpaq->TAB_fail3[p_lpaq->fail2];
                p_lpaq->fail2   = fail | 2U;
            }
        }
    }
    
    c_dec &= 0xFF;
    
    p_lpaq->cc = (p_lpaq->cc<<8) + (p_lpaq->c8>>24);
    p_lpaq->c8 = (p_lpaq->c8<<8) + (((int32_t)p_lpaq->c4)>>24);
    p_lpaq->c4 = (p_lpaq->c4<<8) | c_dec;
    
    matchModelUpdate(&p_lpaq->mm, c_dec, p_lpaq->c4, p_lpaq->c8, p_lpaq->cc);
    
    if (('A'<=c_dec && c_dec<='Z') || ('a'<=c_dec && c_dec<='z')) {
        p_lpaq->h5 = ((p_lpaq->h5<<1) + (c_dec&0xDF)) * 191U;
    } else {
        p_lpaq->pw = p_lpaq->h5 * PW_MUL;
        p_lpaq->h5 = 0;
    }
    
    if (p_lpaq->method == METHOD_TEXT) {
        if ( matchModelPosCond(&p_lpaq->mm, p_lpaq->dpsft) ) {
            uint32_t i;
            p_lpaq->dpsft ++;
            for (i=0; i<MI*MC; i++) {
                p_lpaq->mxr_wx[i] *= 2;
            }
        }
    }
    
    *p_c_dec = exchange_for_text((uint8_t)c_dec, p_lpaq->method);

    return R_OK;
}

static int lpaq8CodecInit (uint8_t *p_buf, size_t buf_len, lpaq8Codec_t *p_lpaq, uint32_t is_compress_in, uint32_t method_in, uint32_t level_in, size_t *p_n_total_allocate_bytes) {
    size_t n_allocate_bytes;
    uint32_t mem = 1U << (level_in+20);
    p_lpaq->method = method_in;
    RET_WHEN_ERR( ariCodecInit(&p_lpaq->ari_codec, is_compress_in, p_buf, buf_len) );

    *p_n_total_allocate_bytes = 0;
    n_allocate_bytes = hashTableInit(&p_lpaq->t1, mem >> 1);                                                           RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = hashTableInit(&p_lpaq->t2, mem);                                                                RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = hashTableInit(&p_lpaq->t3, mem >> 1);                                                           RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = hashTableInit(&p_lpaq->t3, mem >> 1);                                                           RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm0, ((p_lpaq->method==METHOD_TEXT)?LIMIT_SM0_TEXT:LIMIT_SM0), (55<<8));  RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm1, LIMIT_SM1, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm2, LIMIT_SM2, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm3, LIMIT_SM3, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm4, LIMIT_SM4, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm5, LIMIT_SM5, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = stateMapInit(&p_lpaq->sm6, LIMIT_SM6, 768);                                                     RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = secondaryEstimitorInit(&p_lpaq->sse1, LIMIT_APM1, 24*0x10000);                                  RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = secondaryEstimitorInit(&p_lpaq->sse2, LIMIT_APM2, 24*0x800);                                    RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    n_allocate_bytes = matchModelInit(&p_lpaq->mm, mem, p_lpaq->method);                                               RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    
    MEM_ALLOC(uint8_t, p_lpaq->tbase, 0x10000, 0, n_allocate_bytes);                                                   RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    
    p_lpaq->first_bit = 1;
    p_lpaq->c4 = p_lpaq->c8 = p_lpaq->cc = 0;
    p_lpaq->h5 = p_lpaq->pw = 0;
    p_lpaq->fail3 = p_lpaq->fail2 = 0;
    p_lpaq->dpsft = 14;
    
    MEM_ALLOC(int32_t, p_lpaq->mxr_wx, MI*MC, MXR_INIT, n_allocate_bytes);                                             RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
    
    {   // initialize constant lookup tables ---------------------------
        MEM_ALLOC(int32_t , p_lpaq->TAB_stretch , 4096, 0, n_allocate_bytes);                                          RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
        MEM_ALLOC(uint32_t, p_lpaq->TAB_stretch2, 4096, 0, n_allocate_bytes);                                          RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
        MEM_ALLOC(uint32_t, p_lpaq->TAB_squash2 , 4096, 0, n_allocate_bytes);                                          RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
        MEM_ALLOC(uint32_t, p_lpaq->TAB_fail3   ,  256, 0, n_allocate_bytes);                                          RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
        MEM_ALLOC(uint8_t , p_lpaq->TAB_fail2   , 8192, 0, n_allocate_bytes);                                          RET_ERR_IF(R_ERR_MEMORY_RUNOUT, 0==n_allocate_bytes);  *p_n_total_allocate_bytes+=n_allocate_bytes;
        
        {
            uint32_t i, j=0, k;
            for (k=0; k<=4094; k++) { // invert TAB_squash2()
                i = TAB_squash[k];
                p_lpaq->TAB_squash2[k] = i + SQUARD;
                for (; j<=i; j++) {
                    p_lpaq->TAB_stretch [j] = k - 2047;
                    p_lpaq->TAB_stretch2[j] = (uint32_t)k * 23;
                }
            }
        }
        
        p_lpaq->TAB_stretch [4095] = 2047;
        p_lpaq->TAB_stretch2[4095] = 4094 * 23;
        
        {
            uint32_t i;
            for (i=0; i<256; i++) {
                uint32_t pi = 0;
                if (i&  3) pi += 1024;
                if (i& 28) pi += 512;
                if (i&224) pi += 256;
                p_lpaq->TAB_fail3[i] = pi;
            }
        }
        
        {
            int32_t cf1 = (p_lpaq->method==METHOD_TEXT) ? 640 : 1216;
            int32_t cf3 = (p_lpaq->method==METHOD_TEXT) ? 2272: 2592;
            int32_t i;
            for (i=-4096; i<4096; ++i) {
                p_lpaq->TAB_fail2[i+4096] = (uint8_t)( (ABS(i) > cf3) ? 3 : (ABS(i) > cf1) ? 1 : 0 );
            }
        }
    }

    return R_OK;
}

static void lpaq8CodecFree (lpaq8Codec_t *p_lpaq) {
    hashTableFree(&p_lpaq->t1);
    hashTableFree(&p_lpaq->t2);
    hashTableFree(&p_lpaq->t3);
    stateMapFree(&p_lpaq->sm0);
    stateMapFree(&p_lpaq->sm1);
    stateMapFree(&p_lpaq->sm2);
    stateMapFree(&p_lpaq->sm3);
    stateMapFree(&p_lpaq->sm4);
    stateMapFree(&p_lpaq->sm5);
    secondaryEstimitorFree(&p_lpaq->sse1);
    secondaryEstimitorFree(&p_lpaq->sse2);
    matchModelFree(&p_lpaq->mm);
    free(p_lpaq->mxr_wx);
    free(p_lpaq->TAB_stretch);
    free(p_lpaq->TAB_stretch2);
    free(p_lpaq->TAB_squash2);
    free(p_lpaq->TAB_fail3);
    free(p_lpaq->TAB_fail2);
}



int lpaq8C (uint8_t *p_src, size_t src_len, uint8_t *p_dst, size_t *p_dst_len, uint8_t level, size_t *p_mem_usage) {
    size_t i;
    uint32_t method = METHOD_TEXT;
    lpaq8Codec_t lpaq8_codec;

    RET_ERR_IF(R_ERR_UNSUPPORTED    , (level>9));              // invalid level (must be 0~9)
    RET_ERR_IF(R_ERR_INPUT_OVERFLOW , (src_len>=0x7FFFFFFF));  // input file too large
    RET_ERR_IF(R_ERR_OUTPUT_OVERFLOW, (*p_dst_len<9));         // output file too small to contain the header

    {
        size_t observe_len = 32768+4;
        if (observe_len > src_len) observe_len = src_len;
        for (i=0; i<observe_len; i++) {
            if (p_src[i] >= 0x80) {
                method = METHOD_DEFAULT;
                break;
            }
        }
    }

    p_dst[0] = 'p';
    p_dst[1] = 'Q';
    p_dst[2] = '\x08';
    p_dst[3] = '0' + level;
    p_dst[4] = src_len >> 24;
    p_dst[5] = src_len >> 16;
    p_dst[6] = src_len >> 8;
    p_dst[7] = src_len;
    p_dst[8] = method;

    RET_WHEN_ERR( lpaq8CodecInit((p_dst+9), (*p_dst_len-9), &lpaq8_codec, 1, method, level, p_mem_usage) );
    
    for (i=0; i<src_len; i++) {
        uint8_t waste_byte;
        RET_WHEN_ERR( lpaq8CodecByte(&lpaq8_codec, p_src[i], &waste_byte) );  // compress a byte
    }
    
    RET_WHEN_ERR( ariCodecFlush(&lpaq8_codec.ari_codec) );
    
    lpaq8CodecFree(&lpaq8_codec);

    *p_dst_len = lpaq8_codec.ari_codec.p_buf - p_dst;

    return R_OK;
}



int lpaq8D (uint8_t *p_src, size_t src_len, uint8_t *p_dst, size_t *p_dst_len, uint8_t *p_level, size_t *p_mem_usage) {
    size_t dst_len, i;
    uint32_t method;
    lpaq8Codec_t lpaq8_codec;

    RET_ERR_IF(R_ERR_INPUT_OVERFLOW, (src_len<9));                                   // input file too small to contain the header
    RET_ERR_IF(R_ERR_UNSUPPORTED, (p_src[0]!='p' || p_src[1]!='Q' || p_src[2]!=8));  // Check header version, get memory option, file size
    *p_level = (p_src[3] - '0');
    RET_ERR_IF(R_ERR_UNSUPPORTED, (*p_level>9));                                     // invalid level (must be 0~9)
    dst_len  = ((size_t)p_src[4]) << 24;
    dst_len |= ((size_t)p_src[5]) << 16;
    dst_len |= ((size_t)p_src[6]) << 8;
    dst_len |= ((size_t)p_src[7]);
    RET_ERR_IF(R_ERR_OUTPUT_OVERFLOW, (dst_len>=0x7FFFFFFF));                        // output file too large
    RET_ERR_IF(R_ERR_OUTPUT_OVERFLOW, (dst_len>(*p_dst_len)));                       // output file too large
    method   = p_src[8];
    RET_ERR_IF(R_ERR_UNSUPPORTED, (method!=METHOD_DEFAULT && method!=METHOD_TEXT));

    RET_WHEN_ERR( lpaq8CodecInit((p_src+9), (src_len-9), &lpaq8_codec, 0, method, (uint32_t)(*p_level), p_mem_usage) );
    
    for (i=0; i<dst_len; i++) {
        RET_WHEN_ERR( lpaq8CodecByte(&lpaq8_codec, 0, &p_dst[i]) );
    }

    *p_dst_len = dst_len;

    return R_OK;
}

